#include<iostream>
#include<ctime>
#include<eigen3/Eigen/Core>
#include<eigen3/Eigen/Dense>
using namespace std;
#define MATRIX_SIZE 50

int main(int argc,char** argv){
// Eigen 中所有向量和矩阵都是Eigen::Matrix，它是一个模板类。它的前三个参数为：数据类型，行，列
// 声明一个2*3的float矩阵
Eigen::Matrix<float,2,3>matrix_23;
// Vector3d实质上是Eigen::Matrix<double,3,1>,三维向量
Eigen::Vector3d v_3d;
Eigen::Matrix<float,3,1>vd_3d;
// Matrix3d 实质上是 Eigen::Matrix<double,3,3>
Eigen::Matrix3d matrix_33 = Eigen::Matrix3d::Zero(); // 初始化为0
// 如果不确定矩阵大小，可以使用动态大小的矩阵
Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic>matrix_dynamic;
//也可以写成
Eigen::MatrixXd matrix_x;

// 输入数据（初始化）
matrix_23<<1,2,3,4,5,6;
// 输出
cout<<matrix_23<<endl;

for(int i=0;i<2;i++){
  for(int j=0;j<3;j++){
    cout<<matrix_23(i,j)<<"\t";
    cout<<endl;
  }
}

v_3d<<3,2,1;
vd_3d<<4,5,6;
// 但是在Eigen里你不能混合两种不同类型的矩阵，像这样是错的
// Eigen::Matrix<double, 2, 1> result_wrong_type = matrix_23 * v_3d;
// 应该显式转换
Eigen::Matrix<double,2,1> result = matrix_23.cast<double>()*v_3d;
cout<<result<<endl;
Eigen::Matrix<float,2,1> result2 = matrix_23*vd_3d;
cout<<result2<<endl;

matrix_33 = Eigen::Matrix3d::Random(); //随机数矩阵
cout<<matrix_33<<endl;
cout<<matrix_33.transpose()<<endl; // 转置
cout<<matrix_33.sum()<<endl; //各元素和
cout<<matrix_33.trace()<<endl; //迹
cout<<matrix_33.inverse()<<endl; //逆
cout<<matrix_33.determinant()<<endl; // 行列式

// 求特征值
Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d>eigen_solver(matrix_33.transpose()*matrix_33);
cout<<"Eigen values = \n"<<eigen_solver.eigenvalues()<<endl;
cout<<"Eigen vectors = \n"<<eigen_solver.eigenvectors()<<endl;

// 解方程
// 我们求解 matrix_NN * x = v_Nd 这个方程
Eigen::Matrix<double,MATRIX_SIZE,MATRIX_SIZE>matrix_NN;
matrix_NN = Eigen::MatrixXd::Random(MATRIX_SIZE,MATRIX_SIZE);
Eigen::Matrix< double, MATRIX_SIZE,  1> v_Nd;
v_Nd = Eigen::MatrixXd::Random( MATRIX_SIZE,1 );
// 直接求逆 运算量比较大
// 一般选择用QR分解
Eigen::Matrix<double,MATRIX_SIZE,1> x = matrix_NN.colPivHouseholderQr().solve(v_Nd);
}